/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include "../include/web_server.h"
#include <mongoose.h>
#include <thread>
#include <set>
#include <regex>
#include <unordered_map>
#include <vector>
#include <chrono>
#include <mutex>

struct mg_mgr;
struct mg_connection;

namespace El {
namespace WebServer {

// API路由项
struct RouteItem {
    std::string method;
    std::string uri_pattern;
    HttpHandler handler;
    std::regex uri_regex; // 正则表达式对象
};

// WebSocket路由项
struct WebSocketRouteItem {
    std::string uri_pattern;
    WebSocketEventHandler handler;
    std::regex uri_regex; // 正则表达式对象
};

class HttpServerImpl : public IHttpServer {
    DISALLOW_COPY_AND_MOVE(HttpServerImpl);

public:
    static HttpServerImpl &GetInstance();
    HttpServerImpl();
    ~HttpServerImpl() override;

    bool Start() override;
    void Stop() override;
    bool SetMountPoint(const std::string &dir) override;
    void SetSSLCert(const std::string &cert_file, const std::string &key_file) override;
    void AddAuthExemptUrl(const std::string &url_pattern) override;
    void RemoveAuthExemptUrl(const std::string &url_pattern) override;

    // 注册HTTP接口
    bool RegisterHandler(const std::string &method, const std::string &uri_pattern, HttpHandler handler) override;

    // 鉴权相关
    void AddBearerToken(const std::string &token) override;
    void RemoveBearerToken(const std::string &token) override;
    bool ValidateToken(const std::string &token) override;
    void PrintBearerTokens() const; // 打印所有 bearer tokens

    // 新WebSocket接口
    bool RegisterWebSocketHandler(const std::string &uri_pattern, WebSocketEventHandler handler) override;
    bool SendWebSocketTextMessage(void *connection, const std::string &message) override;
    bool SendWebSocketBinaryMessage(void *connection, const std::vector<uint8_t> &data) override;
    void CloseWebSocketConnection(void *connection, int status_code, const std::string &reason) override;
    bool GetWebSocketConnectionInfo(void *connection, WebSocketConnectionInfo &info) override;
    std::vector<void *> GetAllWebSocketConnections(const std::string &uri_pattern = "") override;
    int BroadcastWebSocketMessage(const std::string &uri_pattern, const std::string &message) override;

    // 代理相关接口
    bool RegisterProxyRule(const std::string &uri_pattern, 
                           const std::vector<ProxyTarget> &targets,
                           const ProxyOptions &options = {}) override;
    bool RemoveProxyRule(const std::string &uri_pattern) override;
    void SetProxyGlobalTimeout(int timeout_ms) override;
    void SetProxyGlobalRetry(int retry_count) override;
    void EnableProxyLogging(bool enabled) override;

private:
    static void HandleHttpEvent(struct mg_connection *c, int ev, void *ev_data, void *fn_data);
    void HandleHttpRequest(struct mg_connection *c, int ev, void *ev_data);
    bool MatchRoute(const std::string &method, const std::string &uri, RouteItem *route);
    bool FindWebSocketRoute(const std::string &uri, WebSocketRouteItem *route);
    bool IsAuthExempt(const std::string &uri);
    bool ValidateAuthHeader(const mg_str *auth_header);
    void HandleWebSocketEvent(struct mg_connection *c, int ev, void *ev_data);

    // 代理相关私有方法
    bool HandleProxyRequest(const HttpRequest &request, HttpResponse &response);
    bool MatchProxyRule(const std::string &uri, ProxyRule &matched_rule);
    bool ForwardRequest(const HttpRequest &request, const ProxyRule &rule, HttpResponse &response);
    ProxyTarget SelectTarget(const std::vector<ProxyTarget> &targets, ProxyRule &rule);
    std::string BuildProxyUrl(const ProxyTarget &target, const std::string &uri, const ProxyRule &rule);
    void InitializeCurl();
    void CleanupCurl();

    // libcurl回调函数
    static size_t WriteCallback(void *contents, size_t size, size_t nmemb, std::string *data);
    static size_t HeaderCallback(void *contents, size_t size, size_t nmemb, std::map<std::string, std::string> *headers);

    // WebSocket连接状态
    struct WebSocketConnectionState {
        std::string uri;              // 连接的URI
        mg_connection *conn;          // 连接指针
        WebSocketConnectionInfo info; // 连接详细信息
    };

private:
    // 默认证书路径
    std::string cert_file_;
    std::string key_file_;

    // 鉴权相关
    std::set<std::string> bearer_tokens_;      // Bearer tokens集合
    std::vector<std::regex> auth_exempt_urls_; // 免鉴权URL列表

    mg_mgr *mgr_ = nullptr;
    bool running_ = false;
    std::string root_dir_;                      // 网页根目录
    std::vector<RouteItem> routes_;             // 添加路由表
    std::vector<WebSocketRouteItem> ws_routes_; // WebSocket路由表
    std::thread serverThread_;

    // 代理相关成员变量
    std::vector<ProxyRule> proxy_rules_;          // 代理规则列表
    std::mutex proxy_mutex_;                      // 代理操作互斥锁
    int proxy_global_timeout_ = 5000;             // 全局代理超时
    int proxy_global_retry_ = 3;                  // 全局重试次数
    bool proxy_logging_enabled_ = false;          // 代理日志开关
    bool curl_initialized_ = false;               // curl是否已初始化

    // WebSocket连接状态映射表，键为mg_connection的id字段
    std::unordered_map<int64_t, WebSocketConnectionState> ws_connections_;

    // 保护WebSocket连接状态映射表的互斥锁
    std::mutex ws_mutex_;
};

} // namespace WebServer
} // namespace El